﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks.Sources;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace LxCFD
{
    public partial class Geometry3DBuilder
    {
        private Point3DCollection positions = new Point3DCollection();
        private Int32Collection triangleIndices = new Int32Collection();
        public void AddTriangle(Point3D p0, Point3D p1, Point3D p2)
        {
            int i0 = positions.Count;
            positions.Add(p0);
            positions.Add(p1);
            positions.Add(p2);
            AddTriIndices(i0, i0 + 1, i0 + 2);
        }
        public void AddHexahedron(Point3D startpoint, Vector3D vx, Vector3D vy, Vector3D vz)
        {
            int posStart = positions.Count;
            positions.Add(startpoint);
            positions.Add(startpoint + vx);
            for (int i = 0; i < 2; i++)
            {
                positions.Add(positions[i + posStart] + vy);
            }
            for (int i = 0; i < 4; i++)
            {
                positions.Add(positions[i + posStart] + vz);
            }
            AddTriInd_Plane(2 + posStart, 3 + posStart, 1 + posStart, 0 + posStart);
            AddTriInd_Plane(7 + posStart, 6 + posStart, 4 + posStart, 5 + posStart);
            AddTriInd_Plane(1 + posStart, 3 + posStart, 7 + posStart, 5 + posStart);
            AddTriInd_Plane(3 + posStart, 2 + posStart, 6 + posStart, 7 + posStart);
            AddTriInd_Plane(2 + posStart, 0 + posStart, 4 + posStart, 6 + posStart);
            AddTriInd_Plane(0 + posStart, 1 + posStart, 5 + posStart, 4 + posStart);
        }
        protected void AddTriIndices(int i0, int i1, int i2)
        {
            triangleIndices.Add(i0);
            triangleIndices.Add(i1);
            triangleIndices.Add(i2);
        }
        protected void AddTriInd_Plane(int i0, int i1, int i2, int i3)
        {
            AddTriIndices(i0, i1, i2);
            AddTriIndices(i0, i2, i3);
        }
        public void AddCylinder(Point3D basePoint, Vector3D axis, double radius, bool coverTail, bool coverHead, int thetaDiv = 8)
        {
            throw new NotImplementedException();
        }
        public void AddCone(Point3D basePoint, Vector3D axis, double radius, bool coverTail, int thetaDiv = 8)
        {
            throw new NotImplementedException();
        }
        public void AddArrow(Point3D basePoint, Vector3D axis, double headProportion, double tailRadius, double headRadius, int thetaDiv = 8)
        {
            ArrowFactory factory = new ArrowFactory(thetaDiv);
            if (factory.CreateArrow(basePoint, axis, headProportion, tailRadius, headRadius))
            {
                int posStart = positions.Count;
                foreach (var p in factory.Positions)
                {
                    positions.Add(p);
                }
                foreach (var i in factory.TriangleIndices)
                {
                    triangleIndices.Add(i + posStart);
                }
            }
        }
        public void AddPlaneArrow(Point3D basePoint, Vector3D axis, double tailRadius)
        {
            PlaneArrowFactory factory = new PlaneArrowFactory();
            if (axis.LengthSquared == 0) return;
            factory.CreateArrow(basePoint, axis, tailRadius);
            int posStart = positions.Count;
            foreach (var p in factory.Positions)
            {
                positions.Add(p);
            }
            foreach (var i in factory.TriangleIndices)
            {
                triangleIndices.Add(i + posStart);
            }

        }
        //protected void AddRevolvedTriIndices(int pointId, int circleFirstId, int circleLastId, bool isCircleDir)
        //{
        //    if (isCircleDir)
        //    {
        //        for (int i = circleFirstId; i < circleLastId; i++)
        //        {
        //            AddTriIndices(pointId, i, i + 1);
        //        }
        //        AddTriIndices(pointId, circleLastId, circleFirstId);
        //    }
        //    else
        //    {
        //        for (int i = circleFirstId; i < circleLastId; i++)
        //        {
        //            AddTriIndices(pointId, i + 1, i);
        //        }
        //        AddTriIndices(pointId, circleFirstId, circleLastId);
        //    }
        //}
        //protected void AddRevolvedTriIndices(int circle1FirstId, int circle1LastId, int circle2FirstId, int circle2LastId)
        //{
        //    for (int i1 = circle1FirstId, i2 = circle2FirstId; i1 < circle1LastId; i1++, i2++)
        //    {
        //        AddTriIndices(i1, i1 + 1, i2 + 1, i2);
        //    }
        //    AddTriIndices(circle1LastId, circle1FirstId, circle2FirstId, circle2LastId);
        //}
        //public void AddRevolvedGeom(IEnumerable<Point> points, Point origin2d, Vector directon2d, Point3D origin3d, Vector3D direction3d, int thetaDiv = 8)
        //{

        //}
        //public void AddRevolvedGeom(Point[] points, Point3D origin3d, Vector3D direction3d, int thetaDiv = 8)//points绕Y轴旋转，X值为旋转的半径，Y为距离基点的轴向距离
        //{
        //    int circle1FirstId = 0, cirle1LastId = 0;

        //}
        private void AddTriInd_CenterAndCircle_Forward(Int32Collection triInd, int pointId, int circleFirstId, int circleLastId)
        {
            for (int i = circleFirstId; i < circleLastId; i++)
            {
                AddTriIndices(pointId, i, i + 1);
            }
            AddTriIndices(pointId, circleLastId, circleFirstId);
        }
        private void AddTriInd_CenterAndCircle_Backward(Int32Collection triInd, int pointId, int circleFirstId, int circleLastId)
        {
            for (int i = circleFirstId; i < circleLastId; i++)
            {
                AddTriIndices(pointId, i + 1, i);
            }
            AddTriIndices(pointId, circleFirstId, circleLastId);
        }
        private void AddTriInd_Cylinder_ForwardBackWard(Int32Collection triInd, int circle1FirstId, int circle1LastId, int circle2FirstId, int circle2LastId)
        {
            for (int i1 = circle1FirstId, i2 = circle2FirstId; i1 < circle1LastId; i1++, i2++)
            {
                AddTriInd_Plane(i1, i1 + 1, i2 + 1, i2);
            }
            AddTriInd_Plane(circle1LastId, circle1FirstId, circle2FirstId, circle2LastId);
        }
        private void AddTriInd_Cylinder_BackwardForward(Int32Collection triInd, int circle1FirstId, int circle1LastId, int circle2FirstId, int circle2LastId)
        {
            for (int i1 = circle1FirstId, i2 = circle2FirstId; i1 < circle1LastId; i1++, i2++)
            {
                AddTriInd_Plane(i1 + 1, i1, i2, i2 + 1);
            }
            AddTriInd_Plane(circle1FirstId, circle1LastId, circle2LastId, circle2FirstId);
        }
        public MeshGeometry3D MigrateToMesh(bool freeze = false)
        {
            var mg = new MeshGeometry3D();
            if (this.triangleIndices.Count != 0)
            {
                mg.Positions = this.positions;
                mg.TriangleIndices = this.triangleIndices;
            }
            if (freeze)
            {
                mg.Freeze();
            }
            this.positions = new Point3DCollection();
            this.triangleIndices = new Int32Collection();
            return mg;
        }
    }
}